//
//  DeviceViewController.swift
//  TimeBoat
//
//  Created by Jun on 2022/9/5.
//  Copyright © 2022 Time Boat. All rights reserved.
//

import Foundation


enum SearchType {
    case invalidation, searchList, autoConnect
}

@objc class DeviceConnectedViewController: BaseViewController {
    @IBOutlet weak var mDeviceConnectedView: UIView!
    @IBOutlet weak var mDeviceConnectedName: UILabel!
    @IBOutlet weak var mDeviceConnectedID: UILabel!
    @IBOutlet weak var mDeviceBtnReconnection: UIButton!
    @IBOutlet weak var mBtnDetail: UIButton!
    
    @IBOutlet weak var mSearchDeviceView: UIView!
    @IBOutlet weak var mBtnSearch: UIButton!
    
    private var mDeviceItem: DeviceListItem?
    private let mCenter = NotificationCenter.default
    
    private var mAutoConnectTimer: Timer?
    private var mSearchType: SearchType = .invalidation
    
    private let TAG = LogTag.init(rawValue: "DeviceConnectedViewController")
    
    @objc static func viewController() -> DeviceConnectedViewController {
        return DeviceConnectedViewController()
    }
    
    deinit {
        Log.debug(tag: TAG, "deinit")
        removeObserverHandle()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.hideNaviBar = true
        updateBtnSearchTitle()
        
        addObserverHandle()
        loadData()
        
        updateConnectStateLabel()
    }
    
    private func addObserverHandle() {
        mCenter.addObserver(self, selector: #selector(onAppDidBecomeActiveHandle), name: UIApplication.didBecomeActiveNotification, object: nil)
        mCenter.addObserverBTLEReloadDeviceList(observer: self, selector: #selector(appUpdateHandle), object: nil)
        
        mCenter.addObserver(self, selector: #selector(deviceListUpdateHandle), name: NSNotification.Name.userDeviceListUpdate, object: nil)
        mCenter.addObserver(self, selector: #selector(deviceListClearHandle), name: NSNotification.Name.userDeviceListClear, object: nil)
        
        mCenter.addObserverBTLEBeginSearchPeripheral(observer: self, selector: #selector(beginSearchPeripheralHandle), object: nil)
        mCenter.addObserverBTLEDidDiscoverPeripheral(observer: self, selector: #selector(beginSearchPeripheralHandle), object: nil)
        mCenter.addObserverBTLEStopSearchPeripheral(observer: self, selector: #selector(stopSearchPeripheralHandle), object: nil)
        mCenter.addObserverBTLEDidConnectedPeripheral(observer: self, selector: #selector(updateConnectStateLabel), object: nil)
        mCenter.addObserverBTLEDidConnectFailPeripheral(observer: self, selector: #selector(updateConnectStateLabel), object: nil)
        mCenter.addObserverBTLEDidDisconnectPeripheral(observer: self, selector: #selector(updateConnectStateLabel), object: nil)
    }
    
    private func removeObserverHandle() {
        mCenter.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
        mCenter.removeObserverBTLEReloadDeviceList(observer: self, object: nil)
        
        mCenter.removeObserverBTLEBeginSearchPeripheral(observer: self, object: nil)
        mCenter.removeObserverBTLEDidDiscoverPeripheral(observer: self, object: nil)
        mCenter.removeObserverBTLEStopSearchPeripheral(observer: self, object: nil)
        mCenter.removeObserverBTLEDidConnectedPeripheral(observer: self, object: nil)
        mCenter.removeObserverBTLEDidConnectFailPeripheral(observer: self, object: nil)
        mCenter.removeObserverBTLEDidDisconnectPeripheral(observer: self, object: nil)
    }
    
    @objc func onAppDidBecomeActiveHandle() {
        appUpdateHandle()
    }
    
    @objc func updateReconnectionTitle() {
        self.mDeviceBtnReconnection.setTitle("重连", for: .normal)
        self.mDeviceBtnReconnection.isEnabled = true
        self.mDeviceBtnReconnection.backgroundColor = UIColor.init(red: 1, green: 126/255.0, blue: 20/255.0, alpha: 1)
    }
    
    @objc func updateSearchingTitle() {
        self.mDeviceBtnReconnection.setTitle("搜索中", for: .normal)
        self.mDeviceBtnReconnection.isEnabled = false
        self.mDeviceBtnReconnection.backgroundColor = UIColor.lightGray
    }
    
    @objc func updateConnectingTitle() {
        self.mDeviceBtnReconnection.setTitle("正在连接", for: .normal)
        self.mDeviceBtnReconnection.isEnabled = false
        self.mDeviceBtnReconnection.backgroundColor = UIColor.lightGray
    }
    
    @objc func updateConnectedTitle() {
        self.mDeviceBtnReconnection.setTitle("连接成功", for: .normal)
        self.mDeviceBtnReconnection.isEnabled = false
        self.mDeviceBtnReconnection.backgroundColor = UIColor.lightGray
    }
    
    @objc func beginSearchPeripheralHandle() {
        if mSearchType == .autoConnect {
            updateSearchingTitle()
            
            autoConnectPeripheralHandle()
        }
    }
    
    @objc func stopSearchPeripheralHandle() {
        if mSearchType == .autoConnect {
//            updateReconnectionTitle()
        }
    }
    
    @objc func updateConnectStateLabel() {
        switch (BTLEManager.shared.mConnectionState) {
        case .disconnected:
            updateReconnectionTitle()
            break
        case .connecting:
            updateConnectingTitle()
            break
        case .connected:
            updateConnectedTitle()
            break
        default:
            break
        }
    }
    
    @objc func deviceListUpdateHandle() {
        updateUI()
    }
    
    @objc func deviceListClearHandle() {
        updateUI()
        
        BTLEManager.shared.disconnect()
    }
    
    func updateUI() {
        let deviceList = AccountManager.shareAccount().deviceList
        if (nil != deviceList) {
            let list = deviceList!
            if (list.count > 0) {
                self.mDeviceConnectedView.isHidden = false;
                self.mSearchDeviceView.isHidden = true;
                
                let item = deviceList![0]
                self.mDeviceConnectedName.text = item.name!
                self.mDeviceConnectedID.text = "设备ID: " + item.imei!
                
                self.mDeviceItem = item
            } else {
                self.mDeviceConnectedView.isHidden = true;
                self.mSearchDeviceView.isHidden = false;
            }
        } else {
            self.mDeviceConnectedView.isHidden = true;
            self.mSearchDeviceView.isHidden = false;
        }
    }
    
    private func updateBtnSearchTitle() {
        self.mBtnSearch.setTitle("", for: .normal)
        self.mBtnSearch.setTitle("", for: .selected)
        self.mBtnSearch.setTitle("", for: .highlighted)
        
        self.mBtnDetail.setTitle("", for: .normal)
        self.mBtnDetail.setTitle("", for: .selected)
        self.mBtnDetail.setTitle("", for: .highlighted)
    }
    
    @objc func appUpdateHandle() {
        Log.debug(tag: TAG, "app update handle")
        loadData()
    }
    
    @discardableResult
    private func getDeviceListData(completion: APICompletion<DeviceListItem>? = nil) -> APITASK? {
        let token = AccountManager.shareAccount().token()
        if (nil != token) {
            var params = [String: Any]()
            params["token"] = token
            return API.POST("device/list", params, completion)
        }
        
        return nil
    }
    
    private func loadData() {
        Log.debug(tag: TAG, "load data")
        getDeviceListData { result in
            if (result.suc) {
                var list = result.dataList
                if (nil == list) {
                    list = [DeviceListItem]()
                }
                
                if (list!.count > 0) {
                    AccountManager.shareAccount().saveDeviceList(list!)
                } else {
                    AccountManager.shareAccount().clearDeviceList()
                }
            }
        }
    }
    
    @IBAction func btnDeviceDetailClick() {
        Log.debug(tag: TAG, "btn device detail click")
        AccountManager.loginIfNeed(self) { success, loginModel in
            if (success) {
                let vc = DeviceDetailViewController()
                vc.hidesBottomBarWhenPushed = true
                vc.mDeviceItem = self.mDeviceItem
                self.navigationController?.pushViewController(vc, animated: true)
            }
        }
    }
    
    @IBAction func btnReconnectionClick() {
        Log.debug(tag: TAG, "btn reconnection click")
        
        AccountManager.loginIfNeed(self) {[weak self] success, loginModel in
            if (success) {
                self?.mSearchType = .autoConnect
                self?.autoConnectHandle()
            }
        }
    }
    
    
    @IBAction func btnSearchDeviceClick() {
        Log.debug(tag: TAG, "btn search device click")
        AccountManager.loginIfNeed(self) {[weak self] success, loginModel in
            if (success) {
                self?.mSearchType = .searchList
                self?.autoConnectTimerHandle()
                
                let vc = DeviceSearchViewController.viewController()
                vc.hidesBottomBarWhenPushed = true
                self?.navigationController?.pushViewController(vc, animated: true)
            }
        }
    }
    
    private func autoConnectHandle() {
        Log.debug(tag: TAG, "auto connect handle")
        
        if nil == mAutoConnectTimer {
            Log.debug("create timer")
            
            BTLEManager.shared.startSearch()
            
            mAutoConnectTimer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(autoConnectTimerHandle), userInfo: nil, repeats: false)
            RunLoop.main.add(mAutoConnectTimer!, forMode: .default)
        }
    }
    
    private func timerInvalidte() {
        mAutoConnectTimer?.invalidate()
        mAutoConnectTimer = nil
    }
    
    @objc func autoConnectTimerHandle() {
        Log.debug(tag: TAG, "auto connect time handle")
        
        timerInvalidte()
        BTLEManager.shared.stopSearch()
        updateReconnectionTitle()
    }
    
    private func autoConnectPeripheralHandle() {
        Log.debug(tag: TAG, "auto connect peripheral handle")
        
        let targetMac = AccountManager.shareAccount().deviceMac()
        if targetMac.count > 0 {
            Log.debug(tag: TAG, "target mac \(targetMac)")
            for item in BTLEManager.shared.mPerpheralList {
                Log.debug(tag: TAG, "list mac = \(item.macAddress!)")
                if item.macAddress?.caseInsensitiveCompare(targetMac) == .orderedSame {
                    BTLEManager.shared.connectPeripheralItem(item: item)
                    
                    timerInvalidte()
                    BTLEManager.shared.stopSearch()
                    
                    updateConnectingTitle()
                    break
                }
            }
        }
    }
}
